home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / dme / refs.c < prev    next >
C/C++ Source or Header  |  1997-09-09  |  10KB  |  480 lines

  1. /*
  2.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  3.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  4.  *    DICE-LICENSE.TXT.
  5.  */
  6.  
  7. /*
  8.  *  REFS.C
  9.  *
  10.  *  Bringup a cross reference editor window.  The file S:dme.refs and
  11.  *  dme.refs in the current directory are searched for the reference.
  12.  *  If found, the file specified is searched and the segment specified
  13.  *  loaded as a new file in a new window.
  14.  */
  15.  
  16. #include "defs.h"
  17. #include <libraries/dos.h>
  18.  
  19. Prototype void do_addpath (void);
  20. Prototype void do_rempath (void);
  21. Prototype void do_ctags (void);
  22. Prototype void do_refs (void);
  23. Prototype int searchref (char *, char *, char **, char **, int *, char **);
  24. Prototype int dirpart (char *);
  25.  
  26. Prototype MLIST     PBase;
  27.  
  28.  
  29. #define PEN    struct _PEN
  30.  
  31. PEN {
  32.     MNODE   Node;
  33.     char    *path;
  34. };
  35.  
  36. MLIST    PBase;        /*  special DME paths    */
  37.  
  38. /*
  39.  *  Special DME paths for REF and CTAGS
  40.  */
  41.  
  42. #ifndef NO_DO2
  43.  
  44. void
  45. do_addpath()
  46. {
  47.     PEN *pen;
  48.     short len = strlen(av[1]);
  49.  
  50.     for (pen = (PEN *)PBase.mlh_Head; pen->Node.mln_Succ; pen = (PEN *)pen->Node.mln_Succ) {
  51.     if (strcmp(av[1], pen->path) == 0)
  52.         return;
  53.     }
  54.     if (pen = malloc(sizeof(PEN)+len+2)) {
  55.     pen->path = (char *)(pen + 1);
  56.     strcpy(pen->path, av[1]);
  57.     switch(pen->path[len-1]) {
  58.     case ':':
  59.     case '/':
  60.         break;
  61.     default:
  62.         strcat(pen->path, "/");
  63.     }
  64.     }
  65.     AddTail((LIST *)&PBase, (NODE *)pen);
  66. }
  67.  
  68. void
  69. do_rempath()
  70. {
  71.     PEN *pen, *npen;
  72.  
  73.     for (pen = (PEN *)PBase.mlh_Head; npen = (PEN *)pen->Node.mln_Succ; pen = npen) {
  74.     if (WildCmp(av[1], pen->path)) {
  75.         Remove((NODE *)pen);
  76.         free(pen);
  77.     }
  78.     }
  79. }
  80.  
  81. #endif
  82.  
  83. #ifndef NO_DO_CTAGS
  84.  
  85. /*
  86.  *  Implement ctags
  87.  */
  88.  
  89. void
  90. do_ctags()
  91. {
  92.     char str[64];
  93.     char path[128];
  94.     char buf[128];
  95.     char sbuf[128];
  96.     short xlen;
  97.     short slen;
  98.     short dbaselen;
  99.     BPTR oldlock = CurrentDir((BPTR)Ep->dirlock);
  100.     ED *ed;
  101.  
  102.     {
  103.     short i, j;
  104.  
  105.     for (i = Ep->Column; Current[i] == ' '; ++i);
  106.     for (j = i; ; ++j) {
  107.         short c = Current[j];
  108.         if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_') || (c >= '0' && c <= '9'))
  109.         continue;
  110.         break;
  111.     }
  112.     j -= i;
  113.     if (j > 63)
  114.         j = 63;
  115.     movmem(Current+i, str, j);
  116.     str[j] = 0;
  117.     xlen = j;
  118.     }
  119.     if (!Ep->iconmode)
  120.     title("search tags");
  121.     {
  122.     FILE *fi;
  123.     PEN *pen, *npen;
  124.     long i;
  125.     short j, len;
  126.  
  127.     dbaselen = dirpart(Ep->Name);
  128.     movmem(Ep->Name, path, dbaselen);
  129.     strcpy(path+dbaselen, "tags");
  130.  
  131.     /*
  132.      *  Note: pen not used first pass and set to list head, so next
  133.      *  pass it will be the first element.
  134.      *
  135.      *  Note2:  The file path depends on several factors.  (1) tags in
  136.      *        'current' directory, use path to name of current window.
  137.      *        (2) tags in directory in DME special path, use special
  138.      *        path.  (3) tag entry is a full path name, override
  139.      *        previous directories.
  140.      */
  141.  
  142.     for (pen = (PEN *)&PBase; npen = (PEN *)pen->Node.mln_Succ; pen = npen) {
  143.         mountrequest(0);
  144.         if (fi = fopen(path, "r")) {
  145.         mountrequest(1);
  146.         while ((len = xefgets(fi, buf, 128)) >= 0) {
  147.             for (j = 0; buf[j] && buf[j] != ' '; ++j);
  148.             if (j == 0 || buf[0] == '#')
  149.             continue;
  150.             if (j == xlen && strncmp(str, buf, j) == 0) {
  151.             while (buf[j] == ' ')
  152.                 ++j;
  153.             /*
  154.              *  Extract the file name into str.  If the
  155.              *  filename does not contain an absolute path,
  156.              *  prepend it with such.
  157.              */
  158.             {
  159.                 char prep = 1;
  160.                 for (i = 0; buf[j] && buf[j] != ' '; ++i, ++j) {
  161.                 str[i] = buf[j];
  162.                 if (str[i] == ':')
  163.                     prep = 0;
  164.                 }
  165.                 if (prep) {
  166.                 movmem(str, str + dbaselen, i);
  167.                 movmem(path, str, dbaselen);
  168.                 i += dbaselen;
  169.                 }
  170.             }
  171.             str[i] = 0;
  172.  
  173.             while (buf[j] && buf[j] != '^')     /*  SEARCH ARG */
  174.                 ++j;
  175.             fclose(fi);
  176.             if (buf[j] != '^') {
  177.                 title("tags error");
  178.                 goto done;
  179.             }
  180.             ++j;    /* Skip ^ */
  181.  
  182.             /* UN*X FIX: Dme works for Aztec ctags, which has the format:    */
  183.             /*    <tag>    <file>    /^<pattern>                */
  184.             /* However, ctags under UN*X has the following format:        */
  185.             /*    <tag>    <file>    /^<pattern>[$]/             */
  186.             /* We just ignore the '$' and '/' so that both foramts work     */
  187.             /* Thomas Rolfs 27/3/91                     */
  188.  
  189.             {
  190.                 short i = 0;
  191.  
  192.                 while (buf[j] && buf[j] != '$' && buf[j] != '/') {
  193.                 if (buf[j] == '\\') {
  194.                     sbuf[i++] = buf[++j];
  195.                     ++j;
  196.                 } else {
  197.                     sbuf[i++] = buf[j++];
  198.                 }
  199.                 }
  200.                 sbuf[i] = 0;
  201.             }
  202.  
  203.             /* End of fix.    */
  204.  
  205.             slen = strlen(sbuf);
  206.             if ((ed = finded(str, 0)) == NULL) {
  207.                 strcpy(buf, "newwindow newfile ");
  208.                 strcat(buf, str);
  209.                 do_command(buf);
  210.                 ed = finded(str, 0);
  211.             } else {
  212.                 WindowToFront(ed->Win);
  213.                 ActivateWindow(ed->Win);
  214.             }
  215.             if (ed == NULL) {
  216.                 title("unable to load file");
  217.                 goto done;
  218.             }
  219.             text_switch(ed->Win);
  220.             if (Ep->iconmode)
  221.                 uniconify();
  222.             else
  223.                 text_cursor(0);
  224.             for (i = 0; i < ed->Lines; ++i) {
  225.                 if (strncmp(ed->List[i], sbuf, slen) == 0)
  226.                 break;
  227.             }
  228.             sprintf(buf, "first goto %ld", i+1);
  229.             do_command(buf);
  230.             goto done;
  231.             }
  232.         }
  233.         fclose(fi);
  234.         } else {
  235.         mountrequest(1);
  236.         }
  237.         if (npen->Node.mln_Succ) {
  238.         strcpy(path, npen->path);
  239.         strcat(path, "tags");
  240.         dbaselen = strlen(npen->path);
  241.         }
  242.     }
  243.     title("tag not found");
  244.     }
  245. done:
  246.     CurrentDir(oldlock);
  247. }
  248.  
  249. #endif
  250.  
  251. #ifndef NO_DO_REFS
  252.  
  253. /*
  254.  *  Implement references
  255.  */
  256.  
  257. void
  258. do_refs()
  259. {
  260.     static char str[256];
  261.     static char tmprfile[128];
  262.     static char path[128];
  263.     char *srch;
  264.     char *file;
  265.     char *estr;
  266.     long len;
  267.     int bcnt = 10;
  268.     short i, j;
  269.     short slen, elen;
  270.     FILE *fi, *fj;
  271.     short tmph, tmpw;
  272.     BPTR oldlock = CurrentDir((BPTR)Ep->dirlock);
  273.  
  274.     for (i = Ep->Column; Current[i] == ' '; ++i);     /*  skip spaces     */
  275.  
  276.     {
  277.     char c;
  278.  
  279.     for (j = 0; c = Current[i]; ++i, ++j) {
  280.         if (j == sizeof(str) - 1)
  281.         break;
  282.         str[j] = c;
  283.         if (c >= 'a' && c <= 'z')
  284.         continue;
  285.         if (c >= '0' && c <= '9')
  286.         continue;
  287.         if (c >= 'A' && c <= 'Z')
  288.         continue;
  289.         if (c == '_')
  290.         continue;
  291.         break;
  292.     }
  293.     str[j] = 0;
  294.     strcpy (tmprfile, "t:ref_");
  295.     strncat (tmprfile, str, sizeof(tmprfile) - 32);
  296.     }
  297.  
  298.     title("search .refs");
  299.  
  300.     {
  301.     PEN *pen;
  302.     PEN *npen;
  303.  
  304.     strcpy(path, "dme.refs");       /*  warning, am assuming 8 char name */
  305.     mountrequest(0);
  306.     for (pen = (PEN *)&PBase; npen = (PEN *)pen->Node.mln_Succ; pen = npen) {
  307.         if (searchref(path, str, &srch, &file, &len, &estr)) {
  308.         mountrequest(1);
  309.         goto found;
  310.         }
  311.         if (npen->Node.mln_Succ) {
  312.         strcpy(path, npen->path);
  313.         strcat(path, "dme.refs");
  314.         }
  315.     }
  316.     title("Reference not found");
  317.     mountrequest(1);
  318.     goto done;
  319.     }
  320. found:
  321.     title("search file");
  322.     slen = strlen(srch);
  323.     if (estr)
  324.     elen = strlen(estr);
  325.  
  326.     fi = fopen(file, "r");
  327.     if (fi == NULL) {        /*    try using path prefix    */
  328.     strcpy(str, path);
  329.     strcpy(str + strlen(str) - 8, file);
  330.     fi = fopen(str, "r");
  331.     }
  332.     if (fi) {
  333.     short lenstr;
  334.     if (srch[0] == '@' && srch[1] == '@') {
  335.         fseek(fi, atoi(srch+2), 0);
  336.         if ((lenstr = xefgets(fi, str, 256)) >= 0)
  337.         goto autoseek;
  338.     }
  339.     while ((lenstr = xefgets(fi, str, 256)) >= 0) {
  340.         if (strncmp(str, srch, slen) == 0) {
  341. autoseek:
  342.         title("load..");
  343.         if (fj = fopen(tmprfile, "w")) {
  344.             tmph = 0;
  345.             tmpw = 0;
  346.             do {
  347.             if (lenstr > tmpw)
  348.                 tmpw = strlen(str);
  349.             ++tmph;
  350.             fputs(str, fj);
  351.             fputc('\n', fj);
  352.             if (estr && strncmp(str,estr,elen) == 0)
  353.                 break;
  354.             --len;
  355.             } while ((lenstr=xefgets(fi, str, 256)) >= 0 && len);
  356.             fclose(fj);
  357.             if (tmph > 10)
  358.             tmph = 10;
  359.             if (tmpw > 80)
  360.             tmpw = 80;
  361.             sprintf(str, "openwindow +0+0+%d+%d newfile %s", (tmpw<<3)+24, (tmph<<3)+24, tmprfile);
  362.             do_command(str);
  363.             unlink(tmprfile);
  364.         } else {
  365.             sprintf (str, "Unable to open %s for write", tmprfile);
  366.             title (str);
  367.         }
  368.         fclose(fi);
  369.         free(srch);
  370.         free(file);
  371.         if (estr)
  372.             free(estr);
  373.         goto done;
  374.         }
  375.         if (--bcnt == 0) {        /* check break every so so    */
  376.         bcnt = 50;
  377.         if (breakcheck())
  378.             break;
  379.         }
  380.     }
  381.     fclose(fi);
  382.     title("Search failed");
  383.     } else {
  384.     title("Unable to open sub document");
  385.     }
  386.     free(srch);
  387.     free(file);
  388.     if (estr)
  389.     free(estr);
  390. done:
  391.     CurrentDir(oldlock);
  392. }
  393.  
  394. /*
  395.  *  Reference file format:
  396.  *
  397.  *  `key' `lines' `file' `searchstring'
  398.  *
  399.  *  where `lines' can be a string instead ... like a read-until, otherwise
  400.  *  the number of lines to read from the reference.
  401.  */
  402.  
  403. searchref(file, find, psstr, pfile, plines, pestr)
  404. char *file, *find;
  405. char **psstr, **pfile, **pestr;
  406. long *plines;
  407. {
  408.     FILE *fi;
  409.     char buf[256];
  410.     char *ptr, *base;
  411.     char *b1, *b2, *b3, *b4;
  412.     char quoted;
  413.     short findlen = strlen(find);
  414.  
  415.     if (fi = fopen(file, "r")) {
  416.     while (xefgets(fi, (base=buf), 256) >= 0) {
  417.         if (buf[0]=='#')
  418.         continue;
  419.         ptr = breakout(&base, "ed, &b1);
  420. /*          if (ptr && *ptr && strncmp(ptr, find, findlen) == 0) { */
  421.         if (ptr && *ptr && strcmp(ptr, find) == 0) {
  422.         if (ptr = breakout(&base, "ed, &b2)) {
  423.             *pestr = NULL;
  424.             *plines = atoi(ptr);
  425.             if (*plines == 0) {
  426.             *pestr = (char *)malloc(strlen(ptr)+1);
  427.             strcpy(*pestr, ptr);
  428.             }
  429.             if (ptr = breakout(&base, "ed, &b3)) {
  430.             *pfile = (char *)malloc(strlen(ptr)+1);
  431.             strcpy(*pfile, ptr);
  432.             if (ptr = breakout(&base, "ed, &b4)) {
  433.                 *psstr = (char *)malloc(strlen(ptr)+1);
  434.                 strcpy(*psstr, ptr);
  435.                 fclose(fi);
  436.                 if (b1) free(b1);
  437.                 if (b2) free(b2);
  438.                 if (b3) free(b3);
  439.                 if (b4) free(b4);
  440.                 return(1);
  441.             }
  442.             free(*pfile);
  443.             if (b4)
  444.                 free(b4);
  445.             }
  446.             if (pestr)
  447.             free (*pestr);
  448.             if (b3)
  449.             free (b3);
  450.         }
  451.         if (b2)
  452.             free(b2);
  453.         }
  454.         if (b1)
  455.         free(b1);
  456.     }
  457.     fclose(fi);
  458.     }
  459.     return(0);
  460. }
  461.  
  462. #endif
  463.  
  464. #ifndef NO_DO_CTAGS
  465.  
  466. dirpart(str)
  467. char *str;
  468. {
  469.     short i;
  470.  
  471.     for (i = strlen(str) - 1; i >= 0; --i) {
  472.     if (str[i] == '/' || str[i] == ':')
  473.         break;
  474.     }
  475.     return(i+1);
  476. }
  477.  
  478. #endif
  479.  
  480.